window.maps = {};
window.panels = {};
window.bs = {};
window.utils = {};
window.Q = {};
window.mapDatas = {};
panels.layerTreePanelIndex = undefined;
panels.lastConditionPanelIndex = undefined;
panels.lastResultPanelIndex = undefined;
panels.getCesiumHeight = function() {
    return $('#cesiumContainer').height();
}
panels.getCesiumWidth = function() {
    return $('#cesiumContainer').width();
}
panels.getConditionPanelWidth = function() {
    return $("#panel-result").width();
}
mapDatas.getLayerNameByCaption = function(caption) {
    for (let index = 0; index < CONST_VALUES.GX_Datas.length; index++) {
        const dat = CONST_VALUES.GX_Datas[index];
        if (dat.name == caption)
            return dat.dataSetName;
    }
    return "";
}
mapDatas.getDataInfoByName = function(name) {
    for (let index = 0; index < CONST_VALUES.GX_Datas.length; index++) {
        const dat = CONST_VALUES.GX_Datas[index];
        if (dat.name == name)
            return dat;
    }
    return undefined;
}
mapDatas.getFeatureInfo = function() {
    mapDatas.infoboxContainer = document.getElementById("bubble");
    maps.mapViewer.customInfobox = mapDatas.infoboxContainer;
    maps.mapViewer.pickEvent.addEventListener(function(feature) {
        $("blockquote").html("");
        let attributes = "<div class='infoContent'>";
        for (let att in feature) {
            if (att.toUpperCase().startsWith("SM")) {
                continue;
            }
            if (att.toUpperCase().startsWith("SS")) {
                continue;
            }
            let attValue = feature[att];
            let attr = "<div class='infoItem'>" +
                "<div class='infoBoxAttrName' title='" + att + "'>" + att + "</div>" +
                "<div class='infoBoxAttrSplit'>：</div>" +
                "<div class='infoBoxAttrValue' title='" + attValue + "'>" + attValue + "</div>" +
                "</div>";
            attributes += attr;
        }
        attributes += "</div>";
        $("blockquote").append(attributes);
    });
}
Q.queryBySql = function(datasetName, wsName, sql, fromIndex, toIndex, callback) {
    let sqlParam = new SuperMap.GetFeaturesBySQLParameters({
        queryParameter: {
            name: datasetName + "@" + wsName,
            attributeFilter: sql
        },
        datasetNames: [wsName + ":" + datasetName],
        fromIndex: fromIndex,
        toIndex: toIndex
    });
    L.supermap.featureService(CONST_VALUES.GX_Datas_BaseUrl).getFeaturesBySQL(sqlParam,
        function(serviceResult) {
            if (callback != undefined) {
                callback(serviceResult)
            }
        });
}
Q.query = function(queryObject, callback) {
    var sqlParam = new SuperMap.GetFeaturesBySQLParameters({
        queryParameter: {
            name: queryObject.datasetName + "@" + queryObject.wsName,
            attributeFilter: queryObject.sql
        },
        datasetNames: [queryObject.wsName + ":" + queryObject.datasetName],
        fromIndex: queryObject.fromIndex,
        toIndex: queryObject.toIndex,
        groupBy: queryObject.groupBy,
        fields: queryObject.fields
    });
    L.supermap
        .featureService(CONST_VALUES.GX_Datas_BaseUrl)
        .getFeaturesBySQL(sqlParam, function(serviceResult) {
            if (callback != undefined) {
                callback(serviceResult)
            }
        });
}
utils.guid = function() {
    return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
        let r = Math.random() * 16 | 0,
            v = c == 'x' ? r : (r & 0x3 | 0x8);
        return v.toString(16);
    });
}
bs.registerNavMenus = function() {
    $(".layui-side .layui-nav-child a").click(function(e) {
        const id = e.target.id;
        if (id == undefined) {
            layer.msg('功能未实现！', {
                icon: 7
            });
            return;
        }
        if (id.length === 0) {
            layer.msg('功能未实现！', {
                icon: 7
            });
            return;
        }
        panels.loadPanel("/static/maps/bs/" + id + ".html", e.target.innerText);
    });
    $("#q-Spatial").click(function(e) {
        $("#tool-SpatialQuery").css("display", "inline-block");
    });
}

function onload(Cesium) {
    //初始化viewer部件，添加STK地形服务
    let navigation = false;
    if (location.pathname.indexOf("start") >= 0) {
        navigation = true;
    }
    let viewer = new Cesium.Viewer('cesiumContainer', {
        //sceneModePicker: true,
        navigation: navigation,
        selectionIndicator: false,
    });

    viewer.imageryLayers.addImageryProvider(new Cesium.BingMapsImageryProvider({
        url: 'https://dev.virtualearth.net',
        mapStyle: Cesium.BingMapsStyle.AERIAL,
        key: URL_CONFIG.BING_MAP_KEY
    }));

    maps.mapViewer = viewer;
    maps.scene = viewer.scene;
    $(".cesium-viewer-bottom").remove();
    $('#loadingbar').remove();

    layui.use('element', function() {});
    maps.loadSmScene();

    panels.regEvents();
    panels.setDateTime();
    const helper = new Cesium.EventHelper();
    helper.add(viewer.scene.globe.tileLoadProgressEvent, function(e) {
        if (e == 0 && window.firstLoad) {
            window.firstLoad = false;
            $("#load_bg").remove(); //关闭加载动画
            $(".load_box").remove();
        }
    });
}
panels.setDateTime = function() {
    setInterval(() => {
        let dt = new Date();
        let yyyymmdd = dt.getFullYear() + " " + (dt.getMonth() + 1) + " " + dt.getDate();
        let sec = dt.getSeconds();
        sec = sec < 10 ? "0" + sec : sec + "";
        let time = (dt.getHours() < 12 ? "上午" : "下午") + " " + dt.getHours() + ":" + dt.getMinutes() + ":" + sec;
        $('.datetime .time').html(time);
        $('.datetime .date').html(yyyymmdd);
    }, 1000);
}
panels.menuLevel = {};
panels.regEvents = function() {
    $('.query-type-enum div').click(function(e) {
        $('.query-type-enum div').removeClass("query-type-enum-select");
        $(this).addClass("query-type-enum-select");
        $("#queryType-subType").html('');
        if (panels.lastResultPanelIndex != undefined) {
            layui.layer.close(panels.lastResultPanelIndex);
            layui.layer.closeAll();
        }
        panels.menuLevel[panels.menuLevel.L1] = this;
        let id = $(this).find('span').attr('qs-name');
        if (id == undefined) return;
        $("#queryType-subType").html($(this).find('span').html());
        let htmlUrl = "/static/maps/bs/" + id + ".html";
        $.ajax({
            url: htmlUrl,
            success: function(htmlContext) {
                $('.queryConditionsContainer').html('');
                $('.queryConditionsContainer').html(htmlContext);
                layui.use(['form'], function() {
                    let form = layui.form;
                    form.render();
                });
            },
            error: function() {
                $('.queryConditionsContainer').html('');
                layui.layer.msg('功能未实现！', {
                    icon: 7
                });
            }
        });
    });
    $('.head-menus span').click(function(e) {
        if (panels.lastResultPanelIndex != undefined) {
            layui.layer.close(panels.lastResultPanelIndex);
            layui.layer.closeAll();
        }
        $("#queryType-subType").html('未选择类型');
        $(".query-type-enum div").removeClass('query-type-enum-select ');
        let selected = $(this).hasClass('head-menus-menu-select');
        $('.head-menus span').removeClass('head-menus-menu-select');
        if (!selected) {
            $(this).addClass('head-menus-menu-select');
            $('.q-s-icon').removeClass('qs-hidden');
        } else {
            $('.q-s-icon').addClass('qs-hidden');
            $('.q-s-type').addClass('qs-hidden');
        }
        let qureyOrStatics = $(this).hasClass('qs-q');
        //点击了查询按钮
        if (qureyOrStatics) {
            panels.menuLevel.L1 = 2;
            $('.qs-q').removeClass('qs-hidden');
            $('.qs-s').addClass('qs-hidden');
        } else {
            panels.menuLevel.L1 = 1;
            $('.qs-s').removeClass('qs-hidden');
            $('.qs-q').addClass('qs-hidden');
        }
        if (panels.menuLevel[panels.menuLevel.L1] != undefined) {
            $(panels.menuLevel[panels.menuLevel.L1]).trigger('click');
        }
        $('.queryConditionsContainer').html('');
    });
    $("#cdts-ctrl").click(function(e) {
        var notDisplayCdts = $(this).find('img').eq(0).hasClass('qs-hidden');
        if (notDisplayCdts) {
            $(this).find('img').eq(0).removeClass('qs-hidden');
            $(this).find('img').eq(1).addClass('qs-hidden');
            $('.q-s-type').addClass('qs-hidden');
        } else {
            $(this).find('img').eq(1).removeClass('qs-hidden');
            $(this).find('img').eq(0).addClass('qs-hidden');
            $('.q-s-type').removeClass('qs-hidden');
        }
    });
}

panels.loadPanel = function(htmlUrl, title) {
    let _title = title;
    $.ajax({
        url: htmlUrl,
        success: function(htmlContext) {
            panels.createConditionPanel(htmlContext, _title);
        },
        error: function() {
            layer.msg('功能未实现！', {
                icon: 7
            });
        }
    });
}
panels.createChart = function(xAxis, data, title, subTitle, xTypeName, yTypeName, typeOfECharts) {
    if (data.length == 0) return;
    let xAxisData = [];
    for (let val in data[0]) {
        xAxisData.push(data[0][val][xTypeName])
    }
    let seriesData = [];
    for (let i = 1; i < data.length; i++) {
        let series = {};
        series.name = xAxis[i - 1];
        series.type = typeOfECharts;
        series.data = [];
        for (let j = 0; j < data[i].length; j++) {
            series.data.push(parseFloat(data[i][j][yTypeName]));
        }
        seriesData.push(series);
    }
    const chartDivID = "statistics-Chart";
    const chartDom = "<div id='" + chartDivID + "' style='width:100%;min-height: 360px;height:80%;'></div>";
    $("#panel-result").html($(chartDom));
    const myChart = echarts.init(document.getElementById(chartDivID));

    // 指定图表的配置项和数据
    const option = {
        title: {
            text: title,
            subtext: subTitle,
            left: 'center',
            textStyle: {
                fontSize: '18px',
                color: '#177BA3',
                fontWeight: 'bold'
            }
        },
        tooltip: {},
        legend: {
            bottom: '0',
            left: 'right',
            data: xAxis,
            textStyle: {
                color: "#eee"
            }
        },
        toolbox: {
            feature: {
                magicType: {
                    type: ['line', 'bar', 'stack', 'tiled'],
                    title: ['折线图', '柱状图', '堆叠图', '平铺']
                },
                saveAsImage: { title: "保存图片" }
            }
        },
        xAxis: {
            data: xAxisData,
            name: xTypeName,
            axisLabel: {
                interval: 0,
                rotate: 30,
                formatter: function(value, index) {
                    return value /* + 'mm'*/ ;
                },
                axisLine: {
                    onZero: false,
                    lineStyle: {
                        color: "#fff"
                    }
                },
            }
        },
        yAxis: {
            axisLine: {
                onZero: false,
                lineStyle: {
                    color: "#fff"
                }
            },
            name: yTypeName
        },
        series: seriesData
    };

    // 使用刚指定的配置项和数据显示图表。
    myChart.setOption(option);
    return myChart;
}
panels.createMonitor = function() {
    if (panels.createMonitor.created == true) return;

    panels.createMonitor.created = true;

    /*
    document.body.onclick = function(e) {
        let tmp = "<div style='position:absolute;width:2px;height:2px;display:inline-block;left:" + e.pageX + "px;top:" + e.pageY + "px;z-index:9001;background-color:red;'></div>";
        $(tmp).appendTo($('body'));
    };
    document.body.mouseup = function(e) {
        let tmp = "<div style='position:absolute;width:2px;height:2px;display:inline-block;left:" + e.pageX + "px;top:" + e.pageY + "px;z-index:9001;background-color:green;'></div>";
        $(tmp).appendTo($('body'));
    };
    */
    function imitateClick(oElement, iClientX, iClientY) {
        var oEvent;
        if (document.createEventObject) { //For IE
            oEvent = document.createEventObject();
            oEvent.clientX = iClientX;
            oEvent.clientY = iClientY;
            oElement.fireEvent("onclick", oEvent);
        } else {
            oEvent = document.createEvent("MouseEvents");
            oEvent.initMouseEvent("click", true, true, window, 0, 0, 0, iClientX, iClientY);
            oElement.dispatchEvent(oEvent);
        }
    }
    panels.createMonitor.moniter = imitateClick;
}

panels.createPagesByFeatures = function(params) {
    panels.createMonitor();
    let subTitle = params.subTitle;
    let features = params.features;
    let count = params.count;
    let dataSourceName = params.dataSourceName;
    let dataSetName = params.dataSetName;

    if (features.length == 0) return;
    let tableNew = "<table id='THETABLEID' lay-filter='THETABLEID'></table>";
    const tableNewID = utils.guid();
    while (tableNew.indexOf('THETABLEID') > -1)
        tableNew = tableNew.replace('THETABLEID', tableNewID);
    let cols = [];
    for (const property in features[0].properties) {
        let tmpProperty = property.toUpperCase();
        if (tmpProperty.startsWith("SM") && tmpProperty != "SMID")
            continue;
        if (tmpProperty.startsWith("SS"))
            continue;
        cols.push({ field: property, title: property, sort: true, width: 80 });
    }
    let datas = [];
    for (let i in features) {
        datas.push(features[i].properties);
    }

    let tabControl = "<div class='layui-tab' lay-filter='resultTabControl' id='THETABCONTROLID'>" +
        "<ul class='layui-tab-title'></ul>" +
        "<div class='layui-tab-content'></div></div>";
    let tabControlID = utils.guid();
    tabControl = tabControl.replace('THETABCONTROLID', tabControlID);

    if ($('div[lay-filter="resultTabControl"]').length == 0) {
        $(tabControl).appendTo($("#panel-result"));
    }
    //$(tableNew).appendTo($("#" + tabControlID));

    layui.use('element', function() {
        let element = layui.element;
        element.render();
        let tabID = utils.guid();
        element.tabAdd('resultTabControl', {
            title: subTitle,
            content: tableNew //支持传入html
                ,
            id: tabID
        });
        layui.use('table', function() {
            let table = layui.table;
            table.render({
                elem: '#' + tableNewID,
                data: datas,
                page: true,
                "lay-size": 'sm',
                limit: 6,
                cols: [cols]
            });
            table.on('row(' + tableNewID + ')', function(obj) {
                Q.queryBySql(dataSetName, dataSourceName, "SMID = " + obj.data.SMID, 0, 10, function(result) {
                    if (result.result == undefined) return;
                    var smidInt = parseInt(result.result.features.features[0].properties["SMID"]);
                    let IDs = [smidInt];
                    let theLayer = maps.scene.layers.find(subTitle);

                    if (IDs.length > 0) {
                        theLayer.setSelection(IDs);
                        /*
                        theLayer.setObjsColor(IDs, colorYellow);
                        var idColors = new Cesium.AssociativeArray();
                        idColors.set(smidInt, colorYellow);
                        theLayer.updateObjsColor(idColors);
                        */
                        let pos = result.result.features.features[0].geometry.coordinates.position;
                        maps.scene.terrainProvider.visible = false;
                        let center = Cesium.Cartesian3.fromDegrees(pos.x, pos.y, pos.z);
                        cesiumLocateUtil.flyTo.flyToPoint(center, 30, -45, 200, 1, function() {
                            let cesiumElem = $('.cesium-widget canvas')[0];
                            panels.createMonitor.moniter(cesiumElem, $(cesiumElem).width() / 2, $(cesiumElem).height() / 2);
                        });
                    }
                });
            });
        });
        element.tabChange('resultTabControl', tabID);

        const thisTitle = $('.layui-layer-title');
        thisTitle.addClass("layui-layer-title-transparent");
    });
}
panels.createResultPanelWithChart = function(xAxis, data, title, subTitle, xTypeName, yTypeName, typeOfECharts, callback) {
    layui.use('layer', function() {
        let chart;
        let resizeCb = function(layerno) {
            if (chart == undefined) return;
            chart.resize();
        }
        panels.createPanelBase(title, resizeCb);
        chart = panels.createChart(xAxis, data, title, subTitle, xTypeName, yTypeName, typeOfECharts);

        if (callback != undefined) {
            callback();
        }
    });
}
panels.createPanelBase = function(title, resizeCb) {
    //兼容两个页面
    let pc = $("#panel-condition");
    let theTarget;
    if (pc.length > 0) {
        theTarget = pc.parent();
    } else {
        theTarget = $(".q-s-type");
    }
    const conditionLeft = parseInt(theTarget.css("left").replace('px', ''));
    const conditionWidth = parseInt(theTarget.width());
    const conditionHeight = parseInt(theTarget.height());
    const conditionTop = parseInt(theTarget.css("top").replace('px', ''));
    let x = conditionLeft + conditionWidth + 5 + "px";
    let y = conditionTop + conditionHeight + 10 + "px";
    let offset = ['65px'];
    if (pc.length === 0) {
        x = conditionLeft + "px";
        offset = [y, x]
    }
    panels.lastResultPanelIndex = layer.open({
        id: "panel-result",
        anim: 3,
        area: ['412px', '400px'],
        title: "<span class='q-title-in-Sub-img'></span><span class='q-title-in-Sub-title'>" + title + "</span>",
        skin: 'layui-ext-coolskin',
        offset: offset,
        shade: 0,
        type: 1,
        maxmin: true,
        resizing: function(layero) {
            if (resizeCb)
                resizeCb(layero);
        },
        success: function(layero, index) {}
    });
}
panels.createResultPanelWithDataGrid = function(params, callback) {
    layui.use('layer', function() {
        if (params.features.length == 0) {
            layui.layer.msg(params.title + "下" + params.subTitle + '查询无结果。<br>请重新设置查询条件！');
            return -1;
        }

        panels.createPanelBase(params.title);
        panels.createPagesByFeatures(params);
        if (callback != undefined) {
            callback();
        }
    });
}
panels.createConditionPanel = function(htmlContext, title, callback) {
    layui.use('layer', function() {
        const layer = layui.layer;
        layer.close(panels.layerTreePanelIndex);

        function open() {
            panels.lastConditionPanelIndex = layer.open({
                id: "panel-condition",
                anim: 1,
                area: "380px",
                title: title,
                skin: 'layui-ext-coolskin',
                offset: ['65px', panels.SideWidth() + 5 + "px"],
                shade: 0,
                type: 1,
                content: htmlContext, //这里content是一个DOM，注意：最好该元素要存放在body最外层，否则可能被其它的相对元素所影响
                cancel: function() {
                    if (panels.lastResultPanelIndex != undefined) {
                        layer.close(panels.lastResultPanelIndex);
                    }
                },
                success: function(layero, index) {}
            });
            layui.use(['form'], function() {
                let form = layui.form;
                form.render();
            });
            if (callback != undefined) {
                callback();
            }
        }

        if (panels.lastResultPanelIndex != undefined) {
            layer.close(panels.lastResultPanelIndex);
        }
        if (panels.lastConditionPanelIndex != undefined) {
            layer.close(panels.lastConditionPanelIndex);
        }
        setTimeout(open, 500);
    });
}
panels.SideWidth = function() {
    return $(".layui-side ").width();
}
panels.loadLayerTreePanelByDom = function(domID, callback) {
    layui.use('layer', function() {
        const layer = layui.layer;
        panels.layerTreePanelIndex = layer.open({
            anim: 3,
            id: 'layerTreePanel',
            area: "280px",
            skin: 'layui-ext-coolskin',
            title: ["全部图层", 'font-size:14px;'],
            offset: ['65px', panels.SideWidth() + 5 + "px"],
            shade: 0,
            type: 1,
            content: $('#' + domID), //这里content是一个DOM，注意：最好该元素要存放在body最外层，否则可能被其它的相对元素所影响
            cancel: function() {},
            success: function(layero, index) {}
        });
        if (callback != undefined) {
            callback();
        }
    });
}
panels.clear = function(panelID) {
    if (panelID == undefined) {
        $(".r-panel").remove();
    } else {
        $("#" + panelID).remove();
    }
}
maps.loadLayerTrees = function(layers) {
    const allLayers = [];
    let nodeImage = {
        title: "影像图层",
        id: "影像图层",
        layer: maps.mapViewer.imageryLayers.get(1),
        checked: true
    };
    allLayers.push(nodeImage);
    for (let index = 0; index < layers.length; index++) {
        const layer = layers[index];
        if (layer._isSct) continue;
        const nodeLayerInScene = {
            title: layer.name,
            id: layer.name,
            layer: layer,
            checked: layer.visible
        };
        allLayers.push(nodeLayerInScene);
    }
    $('body').append("<div id='layerTree' ></div>");
    let openThePanel = function() {
        if ($("#layerTree").html().length > 0) {
            panels.loadLayerTreePanelByDom('layerTree');
            return;
        }
        panels.loadLayerTreePanelByDom('layerTree', function() {
            layui.use('tree', function() {
                const tree = layui.tree;
                tree.render({
                    elem: '#layerTree',
                    data: allLayers,
                    showCheckbox: true,
                    showLine: true,
                    oncheck: function(obj) {
                        if (obj.data.layer == undefined) {
                            return;
                        }
                        if (obj.data.layer.isFirstLoad == undefined) {
                            obj.data.layer.isFirstLoad = false;
                            return;
                        }
                        if (obj.data.layer.imageryProvider != undefined) {
                            obj.data.layer.show = obj.checked;
                        } else if (obj.data.layer.layer3DType == "TerrainFileLayer") {
                            maps.scene.terrainProvider.visible = obj.checked;
                        } else {
                            let lyr = maps.scene.layers.find(obj.data.layer.name);
                            lyr.visible = obj.checked;
                        }
                    }
                });
            });
        });
    }
    panels.openLayerTreePanel = openThePanel;
    //openThePanel();
}
maps.loadSmScene = function() {
    $.get(URL_CONFIG.SM_SCENE_LAYERS_01,
        function(lyrs) {
            mapDatas.getFeatureInfo();
            maps.layersInScene = lyrs;
            maps.loadLayerTrees(lyrs);
            for (let index = 0; index < lyrs.length; index++) {
                const lyr = lyrs[index];
                lyr.guid = utils.guid();

                if (lyr.layer3DType === "OSGBLayer") {
                    let sctUrl = URL_CONFIG.SM_SCENE_DATA + lyr.name + "/config"
                    let promise = maps.scene.addS3MTilesLayerByScp(sctUrl, { name: lyr.name });
                    promise.then(function(layer) {
                        let colorYellow = new Cesium.Color(1.0, 1.0, 0.0, 1.0);
                        layer.selectedColor = colorYellow;
                        layer.selectColorType = Cesium.SelectColorType.SILHOUETTE_EDGE;
                        layer.selectedLineColor = colorYellow;
                        let dat = mapDatas.getDataInfoByName(layer.name);
                        if (dat == undefined) return;
                        console.log(dat);
                        layer.setQueryParameter({
                            url: CONST_VALUES.GX_Datas_BaseUrl,
                            dataSourceName: dat.dataSourceName,
                            dataSetName: dat.dataSetName,
                            keyWord: 'SmID'
                        });
                    });
                } else if (lyr.layer3DType === "TerrainFileLayer") {
                    const sctUrl = URL_CONFIG.SM_SCENE_DATA + lyr.name
                    maps.mapViewer.terrainProvider = new Cesium.CesiumTerrainProvider({
                        url: sctUrl,
                        isSct: true,
                        invisibility: true
                    });
                    const x = (lyr.bounds.left + lyr.bounds.right) / 2;
                    const y = (lyr.bounds.top + lyr.bounds.bottom) / 2;
                    maps.scene.camera.setView({
                        destination: new Cesium.Cartesian3.fromDegrees(x, y, 5000)
                    });
                }
            }
            window.firstLoad = true;
        });
}

$(document).ready(function() {
    layui.use(['layer'], function() {
        let layer = layui.layer;

        layer.config({
            extend: 'cool/cool.css'
        });
    });
    if (typeof Cesium !== 'undefined') {
        onload(Cesium);
    }
    bs.registerNavMenus();
    if (location.pathname.indexOf("map1") >= 0) {
        panels.addPanels("basicToolbar");
        panels.addPanels("spatialToolBar");
    }
    if (location.pathname.indexOf("start") >= 0) {
        basicToolbarMethod();
        spatialToolBarMethod();
    }
});

panels.addPanels = function(panelName) {
    $.ajax({
        success: function(result) {
            $('body').append($(result));
        },
        error: function(e) {
            console.error(e);
        },
        url: "/static/maps/panels/" + panelName + ".html"
    });
}

function createTooltip(frameDiv) {
    let tooltip = function(frameDiv) {

        let div = document.createElement('DIV');
        div.className = "twipsy right";

        let arrow = document.createElement('DIV');
        arrow.className = "twipsy-arrow";
        div.appendChild(arrow);

        let title = document.createElement('DIV');
        title.className = "twipsy-inner";
        div.appendChild(title);

        this._div = div;
        this._title = title;
        this.message = '';

        // add to frame div and display coordinates
        frameDiv.appendChild(div);
        let that = this;
        div.onmousemove = function(evt) {
            that.showAt({ x: evt.clientX, y: evt.clientY }, that.message);
        };
    };

    tooltip.prototype.setVisible = function(visible) {
        this._div.style.display = visible ? 'block' : 'none';
    };

    tooltip.prototype.showAt = function(position, message) {
        if (position && message) {
            this.setVisible(true);
            this._title.innerHTML = message;
            this._div.style.left = position.x + 10 + "px";
            this._div.style.top = (position.y - this._div.clientHeight / 2) + "px";
            this.message = message;
        }
    };

    return new tooltip(frameDiv);
}
///basicToolbarMethod
function basicToolbarMethod() {
    const viewer = maps.mapViewer;
    const widget = viewer.cesiumWidget;
    var clampMode = 0;
    var handlerDis, handlerArea, handlerHeight;
    //初始化测量距离
    handlerDis = new Cesium.MeasureHandler(viewer, Cesium.MeasureMode.Distance, clampMode);
    //注册测距功能事件
    handlerDis.measureEvt.addEventListener(function(result) {
        var dis = Number(result.distance);
        var distance = dis > 1000 ? (dis / 1000).toFixed(2) + 'km' : dis.toFixed(2) + 'm';
        handlerDis.disLabel.text = '距离:' + distance;
    });
    handlerDis.activeEvt.addEventListener(function(isActive) {
        if (isActive == true) {
            viewer.enableCursorStyle = false;
            viewer._element.style.cursor = '';
            $('body').removeClass('measureCur').addClass('measureCur');
        } else {
            viewer.enableCursorStyle = true;
            $('body').removeClass('measureCur');
        }
    });

    //初始化测量面积
    handlerArea = new Cesium.MeasureHandler(viewer, Cesium.MeasureMode.Area, clampMode);
    handlerArea.measureEvt.addEventListener(function(result) {
        var mj = Number(result.area);
        var area = mj > 1000000 ? (mj / 1000000).toFixed(2) + 'km²' : mj.toFixed(2) + '㎡'
        handlerArea.areaLabel.text = '面积:' + area;
    });
    handlerArea.activeEvt.addEventListener(function(isActive) {
        if (isActive == true) {
            viewer.enableCursorStyle = false;
            viewer._element.style.cursor = '';
            $('body').removeClass('measureCur').addClass('measureCur');
        } else {
            viewer.enableCursorStyle = true;
            $('body').removeClass('measureCur');
        }
    });

    //初始化测量高度
    handlerHeight = new Cesium.MeasureHandler(viewer, Cesium.MeasureMode.DVH);
    handlerHeight.measureEvt.addEventListener(function(result) {
        var distance = result.distance > 1000 ? (result.distance / 1000).toFixed(2) + 'km' : result.distance + 'm';
        var vHeight = result.verticalHeight > 1000 ? (result.verticalHeight / 1000).toFixed(2) + 'km' : result.verticalHeight + 'm';
        var hDistance = result.horizontalDistance > 1000 ? (result.horizontalDistance / 1000).toFixed(2) + 'km' : result.horizontalDistance + 'm';
        handlerHeight.disLabel.text = '空间距离:' + distance;
        handlerHeight.vLabel.text = '垂直高度:' + vHeight;
        handlerHeight.hLabel.text = '水平距离:' + hDistance;
    });
    handlerHeight.activeEvt.addEventListener(function(isActive) {
        if (isActive == true) {
            viewer.enableCursorStyle = false;
            viewer._element.style.cursor = '';
            $('body').removeClass('measureCur').addClass('measureCur');
        } else {
            viewer.enableCursorStyle = true;
            $('body').removeClass('measureCur');
        }
    });

    //椭球贴地面积
    function calcClampValue(positions) {
        var lonlat = [];
        var value = 0;
        for (var i = 0; i < positions.length; i++) {
            var cartographic = Cesium.Cartographic.fromCartesian(positions[i]);
            var lon = Cesium.Math.toDegrees(cartographic.longitude);

            var lat = Cesium.Math.toDegrees(cartographic.latitude);
            lonlat.push(lon, lat);
        }

        var gemetry = new Cesium.PolygonGeometry.fromPositions({
            positions: Cesium.Cartesian3.fromDegreesArray(lonlat)
        });
        return value;
    }
    //椭球贴地距离
    function calcClampDistance(positions) {
        var lonlat = [];
        var value = 0;
        for (var i = 0; i < positions.length; i++) {
            var cartographic = Cesium.Cartographic.fromCartesian(positions[i]);
            var lon = Cesium.Math.toDegrees(cartographic.longitude);

            var lat = Cesium.Math.toDegrees(cartographic.latitude);
            lonlat.push(lon, lat);
        }
        return value;
    }

    function calcAreaWithoutHeight(positions) {
        var totalLon = 0;
        for (var i = 0; i < positions.length; i++) {
            var cartographic = Cesium.Cartographic.fromCartesian(positions[i]);
            var lon = Cesium.Math.toDegrees(cartographic.longitude);
            totalLon += lon;
        }
        var dh = Math.round((totalLon / positions.length + 6) / 6); //带号
        var centralMeridian = dh * 6 - 3;
        //高斯投影
        var projection = new Cesium.CustomProjection({
            name: "tmerc",
            centralMeridian: centralMeridian,
            primeMeridian: 0,
            standardParallel_1: 0,
            standardParallel_2: 0,
            eastFalse: 500000.0,
            northFalse: 0.0,
            semimajorAxis: 6378137,
            inverseFlattening: 298.257222101

        });
        var cartesians = [];
        for (var i = 0; i < positions.length; i++) {
            var cartographic = Cesium.Cartographic.fromCartesian(positions[i]);

            var cartesian = projection.project(cartographic);
            cartesians.push(cartesian);
        }

        cartesians.push(cartesians[0]); //首尾相接
        var value = Cesium.getPreciseArea(cartesians, "China2000", centralMeridian, dh, 1);
        return value;
    }

    clampMode = 0;
    handlerArea.clampMode = 0;
    handlerDis.clampMode = 0;

    $('#tool-dis').click(function() {
        deactiveAll();
        handlerDis && handlerDis.activate();
    });
    $('#tool-area').click(function() {
        deactiveAll();
        handlerArea && handlerArea.activate();
    });
    $('#tool-height').click(function() {
        deactiveAll();
        handlerHeight && handlerHeight.activate();
    });
    $('#tool-clear').click(function() {
        clearAll();
    });

    function clearAll() {
        handlerDis && handlerDis.clear();
        handlerArea && handlerArea.clear();
        handlerHeight && handlerHeight.clear();
    }

    function deactiveAll() {
        handlerDis && handlerDis.deactivate();
        handlerArea && handlerArea.deactivate();
        handlerHeight && handlerHeight.deactivate();
    }
    $('#tool-fullscreen').click(function() {
        toggleFullScreen();
    });

    function FullScreen(el) {
        var isFullscreen = document.fullScreen || document.mozFullScreen || document.webkitIsFullScreen;
        if (!isFullscreen) { //进入全屏,多重短路表达式
            (el.requestFullscreen && el.requestFullscreen()) ||
            (el.mozRequestFullScreen && el.mozRequestFullScreen()) ||
            (el.webkitRequestFullscreen && el.webkitRequestFullscreen()) || (el.msRequestFullscreen && el.msRequestFullscreen());

        } else { //退出全屏,三目运算符
            document.exitFullscreen ? document.exitFullscreen() :
                document.mozCancelFullScreen ? document.mozCancelFullScreen() :
                document.webkitExitFullscreen ? document.webkitExitFullscreen() : '';
        }
    }

    function toggleFullScreen() {
        FullScreen(document.body);
    }
}

function afterQueryCompleted(features) {
    let selectedFeatures = features;
    let IDs = [];
    const viewer = maps.mapViewer;
    viewer.entities.removeAll();
    for (let i = 0; i < selectedFeatures.length; i++) {
        let value = selectedFeatures[i].fieldValues["0"];
        let feature = selectedFeatures[i];
        for (let j = 0; j < feature.fieldNames.length; j++) {
            let index = j.toString();
            if (j == 0) {
                var des = '<table class="cesium-infoBox-defaultTable"><tbody>' + '<tr><th>' + selectedFeatures[i].fieldNames["0"] + '</th><td>' + selectedFeatures[i].fieldValues["0"] + '</td></tr>';
            } else if (j == feature.fieldNames.length - 1) {
                des += '<tr><th>' + selectedFeatures[i].fieldNames[index] + '</th><td>' + selectedFeatures[i].fieldValues[index] + '</td></tr>' + "</tbody></table>";
            } else {
                des += '<tr><th>' + selectedFeatures[i].fieldNames[index] + '</th><td>' + selectedFeatures[i].fieldValues[index] + '</td></tr>';
            }
        }
        let wIndex = selectedFeatures[i].fieldNames.indexOf("SMSDRIW");
        let eIndex = selectedFeatures[i].fieldNames.indexOf("SMSDRIE");
        let nIndex = selectedFeatures[i].fieldNames.indexOf("SMSDRIN");
        let sIndex = selectedFeatures[i].fieldNames.indexOf("SMSDRIS");

        let startElevationIndex = selectedFeatures[i].fieldNames.indexOf("SSSTART_ELEVATION");
        let endElevationIndex = selectedFeatures[i].fieldNames.indexOf("SSEND_ELEVATION");

        let x = (parseFloat(selectedFeatures[i].fieldValues[wIndex]) + parseFloat(selectedFeatures[i].fieldValues[eIndex])) / 2;
        let y = (parseFloat(selectedFeatures[i].fieldValues[nIndex]) + parseFloat(selectedFeatures[i].fieldValues[sIndex])) / 2;
        let elevation = (parseFloat(selectedFeatures[i].fieldValues[startElevationIndex]) + parseFloat(selectedFeatures[i].fieldValues[endElevationIndex])) / 2;

        viewer.entities.add({
            position: Cesium.Cartesian3.fromDegrees(x, y, elevation),
            billboard: {
                image: '/static/maps/images/pointer.png',
                width: 30,
                height: 40
            },
            description: des
        });
        IDs.push(parseInt(value) + 11);
    }
    let theLayer = maps.scene.layers.find(spatialToolBarMethod.SpatialQuery.currentLayerName);
    if (IDs.length > 0) {
        theLayer.setSelection(IDs);
    }
}
///spatialToolBarMethod
function spatialToolBarMethod() {

    $('#tool-layerCtrl').click(function(e) {
        panels.openLayerTreePanel();
    });
    $('#tool-kw').click(function(e) {
        SpatialQuery.current = false;
        DoKW(false);
    });
    $('#tool-kwLine').click(function(e) {
        SpatialQuery.current = false;
        DoKW(true);
    });
    $('#tool-SpatialQuery').click(function(e) {
        SpatialQuery();
    });
    const viewer = maps.mapViewer;
    const tooltip = createTooltip(viewer._element);

    function SpatialQuery() {
        SpatialQuery.current = true;
        DoKW(false);
    }
    spatialToolBarMethod.SpatialQuery = SpatialQuery;

    function DoKW(isLine) {
        DoKW.isLine = isLine;
        if (DoKW.registered === true) {
            if (isLine !== true) {
                DoKW.handlerPolygonKW.activate();
            } else {
                DoKW.handlerLinenKW.activate();
            }
            return;
        }

        document.getElementById("tool-clear").onclick = function() {
            if (DoKW.handlerPolygonKW)
                DoKW.handlerPolygonKW.clear();
            if (DoKW.handlerLinenKW)
                DoKW.handlerLinenKW.clear();
            maps.scene.globe.removeAllExcavationRegion();
            if (DoKW.registered === true) {
                DoKW.endDraw();
                DoKW.deactivate();
                maps.mapViewer.entities.removeAll();
                maps.scene.globe.removeAllExcavationRegion();
            }
        };
        const handlerPolygonKW = new Cesium.DrawHandler(viewer, Cesium.DrawMode.Polygon, 3);
        const handlerLinenKW = new Cesium.DrawHandler(viewer, Cesium.DrawMode.Line, 3);
        let funActiveEvt = function(isActive) {
            if (isActive == true) {
                viewer.enableCursorStyle = false;
                viewer._element.style.cursor = '';
                $('body').removeClass('drawCur').addClass('drawCur');
            } else {
                viewer.enableCursorStyle = true;
                $('body').removeClass('drawCur');
            }
        };
        handlerPolygonKW.activeEvt.addEventListener(funActiveEvt);
        handlerLinenKW.activeEvt.addEventListener(funActiveEvt);
        let funMovingEvt = function(windowPosition) {
            if (windowPosition.x < 200 && windowPosition.y < 150) {
                tooltip.setVisible(false);
                return;
            }
            if (handlerPolygonKW.isDrawing || handlerLinenKW.isDrawing) {
                tooltip.showAt(windowPosition, '<p>点击确定开挖区域中间点</p><p>右键单击结束绘制</p>');
            } else {
                tooltip.showAt(windowPosition, '<p>点击绘制开挖区域第一个点</p><p>右键单击结束绘制</p>');
            }
        };

        function getSpatialQueryGeometry(result) {
            let positions = result.object.positions;
            let geometries = [];
            for (let i = 0; i < positions.length; i++) {
                let position = positions[i];
                let cartographic = Cesium.Cartographic.fromCartesian(position);
                let longitude = Cesium.Math.toDegrees(cartographic.longitude);
                let latitude = Cesium.Math.toDegrees(cartographic.latitude);

                let queryPoint = { // 查询点对象
                    x: longitude,
                    y: latitude
                };
                geometries.push(queryPoint)
            }
            sqatialQueryFromSvr(geometries);
        }

        handlerPolygonKW.movingEvt.addEventListener(funMovingEvt);
        handlerLinenKW.movingEvt.addEventListener(funMovingEvt);

        let funDrawEvt = function(result) {
            if (result.object.length > 0) {
                result.object.positions = result.object;
            }
            if (DoKW.handlerPolygonKW)
                DoKW.handlerPolygonKW.clear();
            if (DoKW.handlerLinenKW)
                DoKW.handlerLinenKW.clear();
            if (!result.object.positions) {
                DoKW.deactivate();
                if (DoKW.isLine === false) {
                    tooltip.showAt(result, '<p>请绘制正确的多边形</p>');
                    DoKW.handlerPolygonKW.activate();
                } else {
                    tooltip.showAt(result, '<p>请绘制正确的线路</p>');
                    DoKW.handlerLinenKW.activate();
                }
                return;
            }
            let array = [].concat(result.object.positions);
            if (array.length < 2) return;
            tooltip.setVisible(false);
            if (SpatialQuery.current === true) {
                getSpatialQueryGeometry(result);
            }
            let positions = [];
            if (!DoKW.isLine) {
                for (let i = 0, len = array.length; i < len; i++) {
                    let cartographic = Cesium.Cartographic.fromCartesian(array[i]);
                    let longitude = Cesium.Math.toDegrees(cartographic.longitude);
                    let latitude = Cesium.Math.toDegrees(cartographic.latitude);
                    let h = cartographic.height;
                    if (positions.indexOf(longitude) == -1 && positions.indexOf(latitude) == -1) {
                        positions.push(longitude);
                        positions.push(latitude);
                        positions.push(h);
                    }
                }
            } else {
                positions = DoKW.lineBuffer(array);
            }
            let dep = 1000;
            viewer.scene.globe.removeAllExcavationRegion();
            viewer.scene.globe.addExcavationRegion({
                name: 'ggg',
                position: positions,
                height: dep,
                transparent: false
            });
            DoKW.deactivate();
            DoKW.endDraw();
        };
        handlerPolygonKW.drawEvt.addEventListener(funDrawEvt);
        handlerLinenKW.drawEvt.addEventListener(funDrawEvt);

        if (isLine)
            handlerLinenKW.activate();
        else
            handlerPolygonKW.activate();
        DoKW.registered = true;
        DoKW.handlerPolygonKW = handlerPolygonKW;
        DoKW.handlerLinenKW = handlerLinenKW;
    }
    spatialToolBarMethod.DoKW = DoKW;
    DoKW.deactivate = function() {
        if (DoKW.handlerPolygonKW.polygon != undefined)
            DoKW.handlerPolygonKW.polygon.show = false;
        if (DoKW.handlerPolygonKW.polyline != undefined)
            DoKW.handlerPolygonKW.polyline.show = false;
        DoKW.handlerPolygonKW.deactivate();

        if (DoKW.handlerLinenKW.polygon != undefined)
            DoKW.handlerLinenKW.polygon.show = false;
        if (DoKW.handlerLinenKW.polyline != undefined)
            DoKW.handlerLinenKW.polyline.show = false;
        DoKW.handlerLinenKW.deactivate();
    }
    DoKW.endDraw = function() {
        tooltip.setVisible(false);

        viewer.enableCursorStyle = true;
        $('body').removeClass('drawCur');
        DoKW.deactivate();
    }
    DoKW.lineBuffer = function(array) {
        let positions = [];
        let lonLats = [];
        let maxHeight = -1;
        for (let i = 0, len = array.length; i < len; i++) {
            let cartographic = Cesium.Cartographic.fromCartesian(array[i]);
            let longitude = Cesium.Math.toDegrees(cartographic.longitude);
            let latitude = Cesium.Math.toDegrees(cartographic.latitude);
            let h = cartographic.height;
            if (h > maxHeight) maxHeight = h;
            //let h1 = cartographic1.height;
            lonLats.push([longitude, latitude]);
        }

        let polygon = turf.lineString(lonLats, { name: 'lineString' });
        let buffered = turf.buffer(polygon, 0.1, { units: 'kilometers', steps: 1 });
        for (let i = 0; i < buffered.geometry.coordinates[0].length; i++) {
            let coordinate = buffered.geometry.coordinates[0][i];
            positions.push(coordinate[0]);
            positions.push(coordinate[1]);
            positions.push(maxHeight);
        }
        return positions;
    }

    function processCompleted(features) { afterQueryCompleted(features); }

    function sqatialQueryFromSvr(queryPoints) {
        maps.mapViewer.entities.removeAll();
        let lyrs = CONST_VALUES.GX_Datas;
        //debugger;
        let lyrsSelect = '<div class="layui-form" lay-filter="lyrsSelectDiv"><div class="layui-form-item">' +
            '<label class="layui-form-label">选择图层</label><div class="layui-input-block">';
        let listStr = '<input type="radio" checked name=\"GX\" value=\"VALUE\" title="TEXT"/ lyrName3D="LAYER3D">';
        for (let index = 0; index < lyrs.length; index++) {
            const lyr = lyrs[index];
            //debugger;
            if (lyr.name.indexOf("管线") < 0)
                continue;
            let dom = listStr.replace('VALUE', lyr.dataSourceName + ':' + lyr.dataSetName2D);
            dom = dom.replace('TEXT', lyr.name);
            dom = dom.replace('LAYER3D', lyr.dataSetName + "@" + lyr.dataSourceName);
            lyrsSelect += dom;
        }
        lyrsSelect += '</div></div></div>';

        layui.use('layer', function() {
            let layer = layui.layer;
            layer.open({
                id: "panel-layerSelect",
                type: 1,
                area: ["300px", "220px"],
                btn: ['确定'],
                title: "请选择图层",
                skin: 'layui-ext-coolskin',
                content: lyrsSelect, //这里content是一个DOM，注意：最好该元素要存放在body最外层，否则可能被其它的相对元素所影响
                cancel: function(index, layero) {
                    layer.close(index)
                },
                yes: function(e) {
                    let gx = $('input[name="GX"]:checked')[0].value;
                    SpatialQuery.currentLayerName = $('input[name="GX"]:checked').attr("title");
                    let queryObj = {
                        "getFeatureMode": "SPATIAL",
                        "spatialQueryMode": "CONTAIN",
                        "datasetNames": [gx],
                        "geometry": {
                            points: queryPoints,
                            type: "REGION"
                        }
                    };

                    let queryData = JSON.stringify(queryObj); // 转化为JSON字符串作为查询参数
                    let dataUrl = CONST_VALUES.GX_Datas_BaseUrl + "/featureResults.rjson?returnContent=true";
                    $.ajax({
                        type: "post",
                        url: dataUrl,
                        data: queryData,
                        success: function(result) {
                            let resultObj = JSON.parse(result);
                            if (resultObj.featureCount > 0) {
                                processCompleted(resultObj.features);
                            }
                        },
                        error: function(msg) {
                            console.log(msg);
                        }
                    })
                }
            });

            layui.use(['form'], function() {
                let form = layui.form;
                form.render();
            });
        });
    }

    function processFailed(e) {
        layui.use('layer', function() {
            let layer = layui.layer;
            layer.msg(e.error.errorMsg);
        });
    }
}

/*
 * @Author: 苹果园dog
 * @Date: 2020-10-31 21:50:33
 * @LastEditTime: 2020-11-05 23:06:14
 * @LastEditors: Please set LastEditors
 * @Description: Cesium 的各种定位方法汇总，只列出项目中经常使用的，如果不够灵活，可直接调用Cesium官方API，也很方便。
 * Cesium的定位从效果上包含两种：直接定位、飞行定位。在方法封装上，本狗姑且将直接定位分类为zoomTo系列，飞行定位分类flyTo。
 * 定位的对象上包括：坐标点、矩形范围、entities、3dtiles、gltf、kml、geojson、影像、地形、geometry 
 * Cesium的定位主要是使用Camera对象和Viewer对象，Viewer的定位zoomTo,flyTo等方法是较高级别的函数，可以定位到Entity、3dtiles、DataSource等添加到三维球上显示的实体，
 * Viewer的定位方法内部都是调用Camera的相关定位方法，针对不同的定位对象，通过一些列计算得出传入实体的合适定位范围和摄像机视角，然后定位，使用起来很方便。
 * Camera的flyTo、flyToBoundingSphere、lookat、setView等方法是较低级别函数，通过定位坐标和角度参数的传入，精细化控制定位视角，灵活。
 * @FilePath: \web\cesiumS\cesium\cesium\mytest\朝花夕拾\定位\cesiumLocateUtil.js
 */
var cesiumLocateUtil = {
    zoomTo: {

    },
    flyTo: {
        /**
         * @description: 飞行定位到一个笛卡尔空间直角坐标点位置
         * @param {Cartesian3} destination 目标点 Cartesian3
         * @param {Number} heading  默认=0.0   偏航角 正北,由正北向东偏向为正
         * @param {*} pitch  =-90     俯仰角 垂直向下， ENU局部坐标系中XY平面的旋转角度，平面下为负，上为正，
         * @param {*} range    =0.0   距目标点距离
         * @param {*} duration =3   持续时间
         * @param {*} callBack =null   回调函数，定位完成后执行
         */
        flyToPoint: function(destination, heading = 0.0, pitch = -90, range = 0.0, duration = 3, callBack = null) {
            if (!maps.mapViewer) {
                console.log('三维球未初始化！');
                return;
            }
            if (!destination) {
                console.log('定位目标点不对！');
                return;
            }
            var boundingSphere = new Cesium.BoundingSphere(destination, 0.0);
            return maps.mapViewer.camera.flyToBoundingSphere(boundingSphere, {
                duration: duration,
                maximumHeight: undefined,
                complete: function() {
                    if (callBack) {
                        callBack();
                    } else {
                        console.log('定位失败！');
                    }
                },
                cancel: function() {
                    console.log('定位取消！');
                },
                offset: {
                    heading: Cesium.Math.toRadians(heading),
                    pitch: Cesium.Math.toRadians(pitch),
                    range: range
                },
            });

        },

        /**
         * @description: 飞行定位到一个矩形
         * @param {Array.<Cartesian3>} cartesians 笛卡尔坐标数组 Array.<Cartesian3>
         * @param {Number} heading  =0.0   偏航角 正北,由正北向东偏向为正
         * @param {*} pitch  =-90     俯仰角  =-90 ENU局部坐标系，XY平面的旋转角度，平面下为负，上为正，
         * @param {*} scale    =1.0   范围缩放倍率
         * @param {*} duration =3   持续时间
         * @param {*} callBack =null   回调函数，定位完成后执行
         * @return {*}
         */
        flyToRectangle: function(cartesians, heading = 0.0, pitch = -90, scale = 1.0, duration = 3, callBack = null) {
            if (!maps.mapViewer) {
                console.log('三维球未初始化！');
                return;
            }
            if (!Array.isArray(cartesians)) {
                console.log('定位范围不对！');
                return;
            }
            if (scale < 0.1) {
                scale = 1.0;
            }
            var rec = Cesium.Rectangle.fromCartesianArray(cartesians);
            var boundingSphere = Cesium.BoundingSphere.fromRectangle3D(rec);
            boundingSphere.radius = boundingSphere.radius * scale;
            maps.mapViewer.camera.flyToBoundingSphere(boundingSphere, {
                duration: duration,
                maximumHeight: undefined,
                complete: function() {
                    if (callBack) {
                        callBack();
                    } else {
                        console.log('定位失败！');
                    }
                },
                cancel: function() {
                    console.log('定位取消！');
                },
                offset: {
                    heading: Cesium.Math.toRadians(heading),
                    pitch: Cesium.Math.toRadians(pitch),
                    range: 0.0
                }
            });
        },
        flyToEntity(entity, ) {}
    }
}